Shader "Unlit/Terrain"
{
    Properties
    {
        testTexture("Texture", 2D) = "white" {}
        testScale("Scale", float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}
        LOD 200

        Pass
        {
            Name "Terrain"
            Tags { "LightMode"="UniversalForward" }

            HLSLPROGRAM
            #pragma target 3.5
            // 定义顶点和像素着色器
            #pragma vertex Vert
            #pragma fragment Frag

            // 包含必要的URP库
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                float3 normalOS : NORMAL;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                half3 positionWS : TEXCOORD1;
                half3 normalWS : TEXCOORD2;

            };

            const static int maxLayerCount = 8;
            const static float epsilon = 1E-4;
            

            
            CBUFFER_START(UnityPerMaterial)
                
            int baseColourCount;
            int layerCount;
            float3 baseColours[maxLayerCount];
            float baseStartHeights[maxLayerCount];
            float baseBlends[maxLayerCount];
            float baseColourStrength[maxLayerCount];
            float baseTextureScale[maxLayerCount];

            
            float minHeight;
            float maxHeight;
            float testScale;
            CBUFFER_END

            TEXTURE2D(testTexture);
            SAMPLER(sampler_testTexture);

            TEXTURE2D_ARRAY(baseTextures);
            SAMPLER(sampler_baseTextures);


            Varyings Vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS);
                OUT.uv = IN.uv;
                OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
                return OUT;
            }

            //反向插值
            float inverseLerp(float a, float b,float value)
            {
                return saturate((value - a) / (b - a));
            }
            
            half4 Frag(Varyings IN) : SV_Target
            {
                
                float heightPercent = inverseLerp(minHeight,maxHeight,IN.positionWS.y);
                float3 finalColor = 0;
                // for (int i = 0; i < baseColourCount; i++)
                // {
                //     float drawStrength = inverseLerp(-baseBlends[i]/2 -epsilon,baseBlends[i]/2,heightPercent - baseStartHeights[i]) ;
                //     finalColor = finalColor *(1-drawStrength) + baseColours[i] * drawStrength;
                // }

                for (int i = 0; i < layerCount; i++)
                {
                    float drawStrength = inverseLerp(-baseBlends[i]/2 -epsilon,baseBlends[i]/2,heightPercent - baseStartHeights[i]) ;
                    finalColor = finalColor *(1-drawStrength) + baseColours[i] * drawStrength;
                }

                float3 scaleWorldPos =  IN.positionWS /testScale;
                float3 blendAxes = abs(IN.normalWS);
                //防止颜色通道超过1
                blendAxes /= (blendAxes.x + blendAxes.y + blendAxes.z);
                //防止不同角度纹理看起来有割裂感
                float3 xProjection = SAMPLE_TEXTURE2D(testTexture,sampler_testTexture,scaleWorldPos.yz) * blendAxes.x;
                float3 yProjection = SAMPLE_TEXTURE2D(testTexture,sampler_testTexture,scaleWorldPos.xz) * blendAxes.y;
                float3 zProjection = SAMPLE_TEXTURE2D(testTexture,sampler_testTexture,scaleWorldPos.xy) * blendAxes.z;
                

                return half4(finalColor,1);
                return  float4(xProjection+ yProjection + zProjection,1);
            }
            ENDHLSL
        }
    }
    FallBack "Hidden/InternalErrorShader"
}
